<template>
  <div class="daily-flow full-height bg-white content page-content relative-position" style="background-color: #fff; border-radius: 6px">
    <collapse ref="collapse" class="collapse-content after">
      <template v-slot:content>
        <yz-condition-filter
          @resetSearch="resetSearch"
          @onSubmit="onSubmit"
        >
          <div class="q-mr-md q-mb-sm">
            <span class="font-14" style="margin-right: 6px">生产日期:</span>
            <date-picker format="YYYY-MM-DD"
                         :clearable="false"
                         :editable="false"
                         type="date"
                         v-model="queryParams.productDate"
                         placeholder="选择生产日期"
                         style="width: 180px"/>
          </div>
          <select-tree label="所在位置" :sel-tree="queryParams.location" class="margin-r-20 margin-b-10"
                       ref="selectTree"
                       :tree-list="locationOptions" node-key="hash" @treeChange="_changeTreeNode"/>
<!--          <select-tooltip-->
<!--            v-model="queryParams.workshop"-->
<!--            :multiple="false"-->
<!--            :options="workshopOpt"-->
<!--            msg="所在车间"-->
<!--          />-->

          <select-tooltip
            v-model="queryParams.processingDevice"
            isShowAll
            :options="processingDeviceOptions"
            msg="加工设备"
          />
<!--          <yz-input-->
<!--            v-model.trim="queryParams.productSpec"-->
<!--            class="q-mr-md"-->
<!--            title="产品规格"-->
<!--          />-->
        </yz-condition-filter>
        <div class="left box form-inline justify-between items-center">
          <q-btn class="btn margin-r-10"
                 outline
                 color="primary"
                 label="导出excel"
                 :disable="!tableData.length"
                 @click="showExcelDialog"/>
          <q-icon name="iconfont icontubiao-72" class="font-18 text-grey">
            <q-tooltip>报工报检数据取实际操作日期报工的数量，技术员与操作员取实际操作日期的人机绑定的人</q-tooltip>
          </q-icon>
        </div>
      </template>
    </collapse>
    <!--  table表格-->
    <q-table :data="tableData"
             :columns="tableColumns"
             row-key="indexId"
             style="margin-bottom: 62px"
             class="scroll  myTable stick-first-col"
             separator="cell"
             :pagination.sync="pagination"
             :hide-bottom="tableData.length !== 0"
             :loading="tableLoading"
             color="primary">
      <template  v-slot:header-cell-finishedCount="props">
        <q-th style="border-right: 1px solid #d3d3d3;min-width: 120px">
          完工数量
          <span>
            <q-icon name="iconfont icontubiao-72" class="font-18 text-grey" />
            <q-tooltip max-width="300px">完工数量：报工数量+修正产量数量+超产数量</q-tooltip>
          </span>
        </q-th>
      </template>
      <template v-slot:header-cell-badCauses="props">
        <q-th style="padding: 0">
          <div class="full-width td-padding line-height-2">不良原因</div>
          <div class="flex no-wrap border-top" v-if="badCauseItems.length > 0">
            <div class="line-height-2 ellipsis td-padding" style="width: 112px;text-align: left" :class="{'border-right': index !== badCauseItems.length - 1}" v-for="(item, index) in badCauseItems" :key="index">{{ item }}<q-tooltip>{{ item }}</q-tooltip></div>
          </div>
          <div class="border-top td-padding" v-else>--</div>
        </q-th>
      </template>
      <template v-slot:header-cell-haltingCauses="props">
        <q-th style="padding: 0">
          <div class="full-width td-padding line-height-2">{{ statusList[1].label }}原因</div>
          <div class="flex no-wrap border-top" v-if="haltingCauseItems.length > 0">
            <div class="line-height-2 ellipsis td-padding" style="width: 112px;text-align: left" :class="{'border-right': index !== haltingCauseItems.length - 1}" v-for="(item, index) in haltingCauseItems" :key="index">{{ item }}<q-tooltip>{{ item }}</q-tooltip></div>
          </div>
          <div class="border-top td-padding" v-else>--</div>
        </q-th>
      </template>
      <template v-slot:body="props">
        <q-tr>
          <q-td class="td-padding">
            {{ `${props.row.deviceName}(${props.row.assetNumber})` }}
          </q-td>
          <q-td v-for="item in props.cols.length - 1" :key="item">
            <div v-if="props.row.shiftGroupItems.length > 0">
              <div v-for="(shiftGroupItem, index) in props.row.shiftGroupItems" :key="`shiftGroupItem${index}`">
                <div class="full-width bor-bottom item align-left td-padding" :class="{'border-top': index !== 0}" v-if="item < 3" :style="getColHeight(props.row, index)">
                  {{shiftGroupItem[props.cols[item].field] || '--' }}
                </div>
                <div v-else-if="item < 26">
                  <div v-for="(workshopPlanning, wpI) in shiftGroupItem.workshopPlanningGroupItems" :key="`workshopPlanning${wpI}`">
                    <div v-if="item < 7" :style="{'height': (workshopPlanning.processPlanningGroupItems.length > 0 ? tdHeight * workshopPlanning.processPlanningGroupItems.length : tdHeight) + 'px!important'}" class="full-width bor-bottom item align-left td-padding" :class="{'border-top': index !== 0 || wpI !== 0}">
                      {{ workshopPlanning[props.cols[item].field] || '--'}}
                    </div>
                    <div v-else-if="item === 7" :style="{'height': (workshopPlanning.processPlanningGroupItems.length > 0 ? tdHeight * workshopPlanning.processPlanningGroupItems.length : tdHeight) + 'px!important'}" class="full-width bor-bottom item align-left td-padding" :class="{'border-top': index !== 0 || wpI !== 0}">
                      <td-spec :rowData="workshopPlanning"/>
                    </div>
                    <div v-else>
                      <div v-for="(processPlanningGroupItem, ppI) in workshopPlanning.processPlanningGroupItems" :key="`processPlanningGroupItem${ppI}`">
                        <div v-if="props.cols[item].field !== 'badCauses'" :style="{'height': tdHeight + 'px!important'}"  class="full-width bor-bottom item align-left td-padding" :class="{'border-top': index!==0 || wpI !== 0 || ppI !== 0}">{{ processPlanningGroupItem[props.cols[item].field] === undefined ? '--' : processPlanningGroupItem[props.cols[item].field] }}</div>
                        <div v-else :style="{'height': tdHeight + 'px!important'}"  class="full-width bor-bottom item align-left" :class="{'border-top': index!==0 || wpI !== 0 || ppI !== 0}">
                          <div class="td-padding align-left" v-if="processPlanningGroupItem[props.cols[item].field] === undefined || processPlanningGroupItem[props.cols[item].field].length === 0">--</div>
                          <div v-else class="flex no-wrap full-height">
                            <div class="align-left line-height-2 td-padding" style="width: 112px" :class="{'border-right': badIndex !== processPlanningGroupItem[props.cols[item].field].length - 1}" v-for="(badCause, badIndex) in processPlanningGroupItem[props.cols[item].field]" :key="badIndex">{{ badCause.count }}</div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
                <div v-else>
                  <div class="full-width bor-bottom item align-left" :class="{'border-top': index !== 0}" :style="getColHeight(props.row, index)">
                    <div class="td-padding" v-if="item === 26">{{shiftGroupItem[props.cols[item].field] || '--' }}</div>
                    <div v-else-if="item===27" class="flex no-wrap full-height">
                      <div class="align-left line-height-2 td-padding" style="width: 112px" :class="{'border-right': badIndex !== shiftGroupItem[props.cols[item].field].length - 1}" v-for="(haltingCauses, badIndex) in shiftGroupItem[props.cols[item].field]" :key="badIndex">{{ haltingCauses.haltingTime }}</div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
            <div class="full-width bor-bottom item align-left td-padding" v-else>--</div>
          </q-td>
        </q-tr>
      </template>
    </q-table>
    <pagination v-model="pagination.page"
                :page-size="pagination.rowsPerPage"
                :total="pagination.rowsNumber"
                @changePageSize="onPageSizeChange"
                @changePage="onPageChange"
                style="margin-bottom: 20px" />

    <basic-dialog :visible="show"
                  title="导出EXCEL"
                  min-width="350px"
                  is-show-basic-footer
                  :isShowInnerLoading="isShowInnerLoading"
                  @close="show=false"
                  @submit="exportExcel"
    >
      <div class="padding-20">
        <span class="font-16" style="margin-right: 6px">生产日期:</span>
        <date-picker format="YYYY-MM-DD"
                     :clearable="false"
                     :editable="false"
                     range
                     v-model="queryParams.excelDate"
                     placeholder="选择生产日期"
                     style="width: 220px"/>
      </div>
    </basic-dialog>
  </div>
</template>

<script>
import Collapse from 'src/components/collapse'
import { getDeviceIds, getWorkshops } from '../../boot/job/process-order'
import Pagination from '../../components/pagination'
import { getDailyReport, getDailyReportExport } from '../../boot/statistics/daily-flow'
import moment from 'moment'
import { mapActions, mapGetters } from 'vuex'
import _ from 'lodash'
import { getOrganize } from 'src/boot/status-monitor/machine'
import { defaultSchemesClearer } from '../../assets/js/util'
import SelectTree from 'src/components/select-tree'

export default {
  name: 'daily-flow',
  components: {
    Collapse,
    SelectTree,
    Pagination
  },
  data () {
    return {
      exportParams: {}, // 请求数据
      queryParams: {
        location: {
          id: null,
          level: null,
          label: '',
          hash: ''
        }, // 所在位置
        // productDate: new Date(),
        excelDate: [moment().subtract(7, 'days').toDate(), new Date()],
        productDate: new Date(),
        workshop: '',
        processingDevice: ['all']
      },
      // 所在位置数据源
      locationOptions: [],
      workshopOpt: [],
      processingDeviceOptions: [],
      tableData: [],
      tableLoading: false,
      requestId: null, // 导出唯一标识
      // 表格分页配置
      pagination: {
        page: 1, // 当前页码
        rowsPerPage: 15, // 每页条数
        rowsNumber: 0 // 总条数
      },
      tdHeight: 40, // 单元格高度
      show: false,
      isShowInnerLoading: false
    }
  },
  computed: {
    ...mapGetters([
      'client', 'statusList'
    ]),
    badCauseItems () {
      let result = []
      this.tableData.some(item => {
        const shiftGroupItems = item.shiftGroupItems
        if (shiftGroupItems?.length > 0) {
          return shiftGroupItems.some(shiftItem => {
            const workshopPlanningGroupItems = shiftItem.workshopPlanningGroupItems
            if (workshopPlanningGroupItems?.length > 0) {
              return workshopPlanningGroupItems.some(planningItem => {
                const processPlanningGroupItems = planningItem.processPlanningGroupItems
                if (processPlanningGroupItems?.length > 0) {
                  return processPlanningGroupItems.some(item => {
                    if (item?.badCauses?.length > 0) {
                      result = item.badCauses
                      return true
                    }
                  })
                }
              })
            }
          })
        }
      })
      return result.map(item => item.causeName)
    },
    haltingCauseItems () {
      let result = []
      this.tableData.some(item => {
        const shiftGroupItems = item.shiftGroupItems
        if (shiftGroupItems?.length > 0) {
          return shiftGroupItems.some(shiftItem => {
            if (shiftItem?.haltingCauses?.length > 0) {
              result = shiftItem.haltingCauses
              return true
            }
          })
        }
      })
      return result.map(item => item.causeName)
    },
    tableColumns () {
      return [
        { name: 'deviceName', label: '加工设备', field: 'deviceName', align: 'left' },
        { name: 'shiftName', label: '轮班', field: 'shiftName', align: 'left' },
        { name: 'productLineName', label: '产线', field: 'productLineName', align: 'left' },
        { name: 'workshopPlanningNumber', label: '计划编号', field: 'workshopPlanningNumber', align: 'left' },
        { name: 'orderNumber', label: '订单号', field: 'orderNumber', align: 'left' },
        { name: 'customerName', label: '客户名称', field: 'customerName', align: 'left' },
        { name: 'productName', label: '加工产品 ', field: 'productName', align: 'left' },
        { name: 'productStandard', label: '产品规格 ', field: 'productStandard', align: 'left' },
        { name: 'operatorName', label: '操作员', field: 'operatorName', align: 'left' },
        { name: 'technicianName', label: '技术员', field: 'technicianName', align: 'left' },
        { name: 'processCount', label: '循环加工数', field: 'processCount', align: 'left' },
        { name: 'processTime', label: '预计加工工时', field: 'processTime', align: 'left' },
        { name: 'averageProcessTime', label: '平均加工工时', field: 'averageProcessTime', align: 'left' },
        { name: 'totalProcessTime', label: '合计预计工时', field: 'totalProcessTime', align: 'left' },
        { name: 'actualProcessTime', label: '合计实际工时', field: 'actualProcessTime', align: 'left' },
        { name: '"processName', label: '加工工序 ', field: 'processName', align: 'left' },
        { name: 'planningCount', label: '计划数量', field: 'planningCount', align: 'left' },
        { name: 'finishedCount', label: '完工数量', field: 'finishedCount', align: 'left' },
        { name: 'finishedRate', label: '达成率', field: 'finishedRate', align: 'left' },
        { name: 'passCount', label: '合格数量', field: 'passCount', align: 'left' },
        { name: 'passRate', label: '合格率', field: 'passRate', align: 'left' },
        { name: 'failCount', label: '不良数量', field: 'failCount', align: 'left' },
        { name: 'failRate', label: '不良率', field: 'failRate', align: 'left' },
        { name: 'qualityCount', label: '质检数量', field: 'qualityCount', align: 'left' },
        { name: 'qualityDefectiveRate', label: '质检不良率', field: 'qualityDefectiveRate', align: 'left' },
        { name: 'badCauses', label: '不良原因', field: 'badCauses', align: 'left' },
        { name: 'shiftHaltingTime', label: `${this.statusList[1].label}时长`, field: 'shiftHaltingTime', align: 'left' },
        { name: 'haltingCauses', label: `${this.statusList[1].label}原因`, field: 'haltingCauses', align: 'left' }
      ]
    }
  },
  watch: {
    'queryParams.workshop': {
      immediate: true,
      handler: function (val) {
        if (val) {
          this.getDeviceIds()
        }
      }
    }
  },
  created () {
    this.init()
  },
  mounted () {
    this.saveCustomerSet()
  },
  methods: {
    ...mapActions([
      'saveCustomerSet'
    ]),
    /**
     * 选择组织机构树节点
     * @param {number} val
     */
    _changeTreeNode: function (val, init = false) {
      if (val.id && val.label && val.hash) {
        this.queryParams.location.id = val.id
        this.queryParams.location.level = val.level
        this.queryParams.location.label = val.label
        this.queryParams.location.hash = val.hash
        // 获取设备
        this.workshopId = val.level === 2 ? val.id : val.workshopId
        this.getDeviceIds()
      } else {
        this.queryParams.location = {
          id: null,
          level: null,
          label: '',
          hash: ''
        }
        this.queryParams.deviceIds = null
        this.deviceOptionsDetail = {}
        this.deviceOptions = []
      }
    },
    init () {
      this.locationOptions = []
      // 获取组织机构树
      getOrganize().then(res => {
        // 去除 default 节点
        let clearTree = defaultSchemesClearer.clear(res.data)

        // 重新组织 tree
        clearTree.forEach(reorganize)

        function reorganize (node) {
          // 为节点添加唯一键，用于 tree 组件标识唯一节点
          node.uniqueKey = node.level + ':' + node.id

          if (node.children instanceof Array) {
            node.children.forEach(reorganize)
          }
        }
        this.locationOptions = clearTree
        this.queryParams.location = Object.assign({}, clearTree[0])

        this.$refs.selectTree.setValue(this.queryParams.location)

        this._changeTreeNode(this.queryParams.location)
      })
      // this.getWorkshops().then(() => {
      //   this.getTableData()
      // })
    },
    // 获取加工设备
    getDeviceIds () {
      const params = {
        level: this.queryParams.location.level,
        schemeId: this.queryParams.location.id
      }
      getDeviceIds(params).then(res => {
        this.devicesMap = {}
        let devicesOption = []
        if (res.data.length) {
          res.data.forEach(item => {
            this.devicesMap[item.id] = item.name
            devicesOption.push({
              assetNumber: item.assetNumber,
              'label': `${item.name}(${item.assetNumber})`,
              'value': item.id
            })
          })
        }
        this.queryParams.processingDevice = ['all']
        this.processingDeviceOptions = devicesOption
      })
    },
    getTableData () {
      if (!this.queryParams.location.id) {
        this.$message.warning('请选择所在位置')
        return
      }
      const params = {
        workDate: moment(this.queryParams.productDate).format('YYYY-MM-DD'),
        schemaId: this.queryParams.location.id,
        schemaLevel: this.queryParams.location.level
      }
      console.log(this.queryParams.processingDevice.indexOf('all'))
      this.queryParams.processingDevice.indexOf('all') <= -1 && (params['deviceIds'] = this.queryParams.processingDevice)
      this.exportParams = _.cloneDeep(params)
      // const selWorkshop = this.workshopOpt.find(item => item.value === this.queryParams.workshop)
      this.exportParams['workshopName'] = this.queryParams.location.label
      params.pageNum = this.pagination.page
      params.pageSize = this.pagination.rowsPerPage
      this.tableLoading = true
      getDailyReport(params).then(res => {
        this.pagination.rowsNumber = res.total
        this.tableData = res.list
      }).finally(() => {
        this.tableLoading = false
      })
    },
    /**
     * 计算单元格高度
     */
    getColHeight (row, index) {
      let count = 0
      if (row.shiftGroupItems.length > 0) {
        const currentGroup = row.shiftGroupItems[index].workshopPlanningGroupItems
        if (currentGroup && currentGroup.length > 0) {
          currentGroup.forEach(item => {
            count += item.processPlanningGroupItems.length
          })
        }
      } else {
        count = 1
      }
      return { 'height': this.tdHeight * count + 'px!important' }
    },
    // 获取加工车间
    getWorkshops () {
      return new Promise((resolve) => {
        getWorkshops().then(res => {
          this.workshopOpt = res.data
          if (this.workshopOpt && this.workshopOpt.length > 0) {
            this.queryParams.workshop = this.workshopOpt[0].value
            resolve()
          }
        })
      })
    },
    // 重置按钮
    resetSearch () {
      Object.assign(this.queryParams, this.$options.data().queryParams)
      this.queryParams.location = Object.assign({}, this.locationOptions[0])
      this.$refs.selectTree.setValue(this.queryParams.location)
      this._changeTreeNode(this.queryParams.location, false)
    },
    // 查询按钮
    onSubmit () {
      this.getTableData()
    },
    // 获取导出报表名称
    getExportName () {
      let name = moment(this.exportParams.workDate).format('YYYY-MM-DD') + '_日流水报表.xls'
      return name
    },
    // 导出excel
    exportExcel () {
      if (Math.abs(moment(this.queryParams.excelDate[1]).diff(this.queryParams.excelDate[0], 'days')) >= 31) {
        this.$message.warning('日期范围不可超过31天')
        return
      }
      // const selWorkshop = this.workshopOpt.find(item => item.value === this.queryParams.workshop)
      const exportParams = {
        ...this.exportParams,
        startDate: moment(this.queryParams.excelDate[0]).format('YYYY-MM-DD'),
        endDate: moment(this.queryParams.excelDate[1]).format('YYYY-MM-DD')
      }
      const params = [{ name: '日流水报表' }]
      const res = this.$getUploadPath(params, '')
      this.requestId = res.fileNameNew
      exportParams['requestId'] = res.fileNameNew
      this.onSubscribe()
      this.$q.loading.show()
      getDailyReportExport(exportParams).then(res => {
        this.show = false
        if (res.code + '' !== '1200') {
          this.$showErrTips('导出异常，请稍后重试')
          this.closeUnsubscribeTopic()
        }
      }).catch(res => {
        this.closeUnsubscribeTopic()
      })
    },
    onSubscribe () {
      if (this.client) {
        this.client.subscribe(
          `${this.CommonConfig.socketConfig.SOCKET_TOPIC.uploadFile.subscribeTopic}${this.requestId}`, this.onMessageArrived, { id: `${this.requestId}` }
        )
      } else {
        setTimeout(() => {
          this.onSubscribe()
        }, 200)
      }
    },
    async onMessageArrived (message) {
      let msg = JSON.parse(message.body).data
      if (msg.requestId !== this.requestId) {
        return
      }
      if (msg.code + '' !== '200') {
        this.$showErrTips('导出异常，请稍后重试')
        this.closeUnsubscribeTopic()
        return
      }
      const name = moment(this.queryParams.excelDate[0]).format('YYYY-MM-DD') + '-' + moment(this.queryParams.excelDate[1]).format('YYYY-MM-DD')
      await this.$saveFileForBlob(msg.data, `${name}_日流水报表.xls`)
      this.closeUnsubscribeTopic()
      this.$message.success('数据请求成功,请保存文件')
    },
    closeUnsubscribeTopic () {
      this.client.unsubscribe(`${this.requestId}`)
      this.$q.loading.hide()
    },

    showExcelDialog () {
      this.show = true
      this.queryParams.excelDate = [this.queryParams.productDate, this.queryParams.productDate]
    },
    /**
     * on 分页组件的每页条数发生改变
     * @param val 每页条数
     */
    onPageSizeChange: function (val, page) {
      this.pagination.rowsPerPage = val
      page && (this.pagination.page = page)
      this.getTableData()
    },

    /**
     * on 分页组件的页码发生改变
     * @param val 页码
     */
    onPageChange: function (val) {
      this.pagination.page = val
      this.getTableData()
    }
  }
}
</script>

<style scoped lang="scss">
/deep/ .q-table td{
  padding: 0;
}
.td-padding{
  padding: 0 16px!important;
}
.align-left {
  display: flex;
  align-items: center;
  justify-content: flex-start;
}
.border-top {
  border-top: 1px solid #d3d3d3;
}
.border-right {
  border-right: 1px solid #d3d3d3;
}
.line-height-2{
  line-height: 2
}
/deep/ .q-table thead tr th:first-child{
  z-index: 5;
  box-shadow: 3px 1px 3px rgba(0,0,0,0.1);
}
.padding-l-16{
  padding-left: 16px;
}
.tips{
  position: absolute;
  left: 20px;
  bottom: 20px;
  color: #999999;
}
>>>.q-table--cell-separator th{
  border-right: 1px solid #d3d3d3 !important;
}
</style>
